package com.xh.one2one.knowledgeSystem.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.tiku.bean.dto.QuestionDto;
import com.xh.bussiness.tiku.dao.QuestionTypeRelationMapper;
import com.xh.bussiness.tiku.model.Knowledge;
import com.xh.bussiness.tiku.model.Question;
import com.xh.bussiness.tiku.model.QuestionImportLog;
import com.xh.bussiness.tiku.model.QuestionTypeRelation;
import com.xh.bussiness.tiku.service.IKnowledgeService;
import com.xh.bussiness.tiku.service.IQuestionImportLogService;
import com.xh.bussiness.tiku.service.IQuestionService;
import com.xh.bussiness.tiku.service.IQuestionTypeRelationService;
import com.xh.core.util.ObjectUtils;
import com.xh.one2one.knowledgeSystem.bean.dto.KnowledgeContentDto;
import com.xh.one2one.knowledgeSystem.bean.request.KnowledgeContentImport;
import com.xh.one2one.knowledgeSystem.bean.request.KnowledgeContentRequest;
import com.xh.one2one.knowledgeSystem.bean.request.KnowledgeTemplateModuleRequest;
import com.xh.one2one.knowledgeSystem.model.KnowledgeContent;
import com.xh.one2one.knowledgeSystem.dao.KnowledgeContentMapper;
import com.xh.one2one.knowledgeSystem.model.KnowledgeManager;
import com.xh.one2one.knowledgeSystem.model.KnowledgeTemplate;
import com.xh.one2one.knowledgeSystem.model.KnowledgeTemplateModule;
import com.xh.one2one.knowledgeSystem.service.IKnowledgeContentService;
import com.xh.core.service.impl.BaseServiceImpl;
import com.xh.one2one.knowledgeSystem.service.IKnowledgeManagerService;
import com.xh.one2one.knowledgeSystem.service.IKnowledgeTemplateModuleService;
import com.xh.one2one.knowledgeSystem.service.IKnowledgeTemplateService;
import com.xh.tools.handout.data.dto.QuestionDTO;
import com.xh.tools.handout.util.HandoutUtils;
import com.xh.tools.question.constant.QuestionTypeEnum;
import org.apache.catalina.manager.ManagerServlet;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.jsoup.Jsoup;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xh.core.bean.XhPage;
import com.xh.core.util.StringUtils;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 知识元管理的内容 服务实现类
 * </p>
 *
 * @author tw
 * @since 2020-12-22
 */
@Service
public class KnowledgeContentServiceImpl extends BaseServiceImpl<KnowledgeContentMapper, KnowledgeContent> implements IKnowledgeContentService {

    @Autowired
    private IKnowledgeManagerService knowledgeManagerService;
    @Autowired
    private IKnowledgeTemplateModuleService templateModuleService;
    @Autowired
    private IQuestionService questionService;
    @Autowired
    private IKnowledgeService knowledgeService;
    @Autowired
    private IQuestionTypeRelationService questionTypeRelationService;
    @Autowired
    private IQuestionImportLogService questionImportLogService;

    @Override
    public XhPage queryKnowledgeContentPage(XhPage page, KnowledgeContentRequest bean) {
        QueryWrapper qw = new QueryWrapper<KnowledgeContent>();
        //拼装条件
        qw = prepareParams(bean, qw);
        if (!StringUtils.isEmpty(bean.getKnowledgeId())) {
            qw.eq("knowledge_id", bean.getKnowledgeId());
        }

        return (XhPage) this.dao.selectPage(page, qw);
    }

    @Override
    public List queryKnowledgeContent(KnowledgeContentRequest bean) {
        QueryWrapper qw = new QueryWrapper<KnowledgeContent>();
        //拼装条件
        qw = prepareParams(bean, qw);
        qw.eq("pid", bean.getPid());
        return this.dao.selectList(qw);
    }

    @Override
    public List<KnowledgeContentDto> queryAllContent(KnowledgeContentRequest bean) {
        List<KnowledgeContentDto> ret = new ArrayList<>();

        QueryWrapper<KnowledgeContent> qw = new QueryWrapper<>();
//        qw.eq("pid",bean.getPid());
        qw.eq("module_id", bean.getModuleId());
        qw.orderByAsc("sort_num");
        List<KnowledgeContentDto> contents = this.selectList(qw, KnowledgeContentDto.class);
        if (null == contents || contents.size() == 0) {
            KnowledgeTemplateModuleRequest request = new KnowledgeTemplateModuleRequest();
            request.setPid(bean.getTemplateId());
            List<KnowledgeTemplateModule> modules = templateModuleService.queryKnowledgeTemplateModule(request);
            for (int i = 0; i < modules.size(); i++) {
                KnowledgeTemplateModule module = modules.get(i);
                KnowledgeContent knowledgeContent = new KnowledgeContent();
                boolean empty = StringUtils.isEmpty(module.getCssContent());
                if (empty) {
                    knowledgeContent.setTitle(module.getTitle());
                    knowledgeContent.setCssTitle(module.getTitle());
                } else {
                    knowledgeContent.setCssTitle(module.getCssContent());
                    knowledgeContent.setTitle(Jsoup.parse(module.getCssContent()).text());
                }
                knowledgeContent.setContent(module.getSubtype());
                knowledgeContent.setModuleId(bean.getModuleId());
                knowledgeContent.setCssType(module.getCssType());
                knowledgeContent.setType(1);
                knowledgeContent.setSortNum(i + 1);
                this.dao.insert(knowledgeContent);

                KnowledgeContentDto dto = new KnowledgeContentDto();
                BeanUtils.copyProperties(knowledgeContent, dto);
                ret.add(dto);
            }
        } else {
            fillData(contents);
            ret.addAll(contents);
        }

        return ret;
    }


    @Override
    public void update(List<KnowledgeContent> request) {
        for (int i = 0; i < request.size(); i++) {
            KnowledgeContent knowledgeContent = request.get(i);
            knowledgeContent.setSortNum(i + 1);
            String cssTitle = knowledgeContent.getCssTitle();
            String text = Jsoup.parse(cssTitle).text();
            knowledgeContent.setTitle(text);
            this.dao.updateById(knowledgeContent);
        }
    }

    @Override
    public void reSortData(KnowledgeContent bean) {
        QueryWrapper qw = new QueryWrapper<KnowledgeContent>();

        qw.eq("module_id", bean.getModuleId());
        qw.ge("sort_num", bean.getSortNum());
        List<KnowledgeContent> list = this.dao.selectList(qw);
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                KnowledgeContent knowledgeContent = list.get(i);
                Integer sortNum = knowledgeContent.getSortNum();
                knowledgeContent.setSortNum(sortNum + 1);
                this.dao.updateById(knowledgeContent);
            }
        }

    }

    @Override
    public void batchSave(List<KnowledgeContent> knowledgeContent) {
        if (knowledgeContent.isEmpty()) {
            return;
        }
        //先删除
        KnowledgeContent kc = knowledgeContent.get(0);
//        QueryWrapper<KnowledgeContent> qw = new QueryWrapper<>();
//        qw.eq("module_id", kc.getModuleId());
        this.dao.deleteByModuleId(kc.getModuleId());

        for (int i = 0; i < knowledgeContent.size(); i++) {
            KnowledgeContent content = knowledgeContent.get(i);
            content.setSortNum(i + 1);
        }
        this.batchInsert(knowledgeContent);
    }

    @Override
    public KnowledgeContent importFromWord(KnowledgeContentImport knowledgeContentImport, String rootPath) {
        String subjectId = knowledgeContentImport.getSubjectId();
        Integer importType = knowledgeContentImport.getImportType();
        String moduleId = knowledgeContentImport.getModuleId();
        List<Map<String, Object>> relationMap = questionTypeRelationService.queryRelationMapBySubject(subjectId);
        List<Map<String, Object>> modules = HandoutUtils.parse(rootPath + knowledgeContentImport.getFilePath(), relationMap);

        // importType == 1 追加内容
        Integer maxSortNum = 0;
        if (importType != null && importType == 1) {
            QueryWrapper<KnowledgeContent> qw = new QueryWrapper<>();
            qw.eq("module_id", moduleId);
            List<KnowledgeContent> oldContents = super.queryByCondition(qw);
            maxSortNum = oldContents.stream().map(KnowledgeContent::getSortNum).max((a, b) -> Integer.compare(a, b)).get();
        }
        // importType == 2 覆盖内容
        if (importType != null && importType == 2) {
            QueryWrapper<KnowledgeContent> qw = new QueryWrapper<>();
            qw.eq("module_id", moduleId);
            super.deleteByCondition(qw);
        }
        boolean hasQuestion = false;
        List<QuestionDto> questionDtos = new ArrayList<>();
        List<KnowledgeContent> contents = new ArrayList<>();
        for (Map<String, Object> module : modules) {
            Integer type = MapUtils.getInteger(module, "type");
            // 模块
            if (type == 1) {
                KnowledgeContent contentModule = new KnowledgeContent();
                contentModule.setType(type);
                contentModule.setModuleId(moduleId);
                contentModule.setCssTitle(MapUtils.getString(module, "name"));
                contentModule.setSortNum(maxSortNum + contents.size());
                contents.add(contentModule);
            }
            // 知识元
            if (type == 3) {
                String name = MapUtils.getString(module, "name");
                name = name.substring(1, name.length() - 1);
                if (name.contains(":")) {
                    name = StringUtils.removeStartAndEndBlank(name.split(":")[1]);
                }
                QueryWrapper<Knowledge> qw = new QueryWrapper<>();
                qw.eq("name", name);
                Knowledge knowledge = knowledgeService.selectFirst(qw);
                if (knowledge != null) {
                    KnowledgeContent contentModule = new KnowledgeContent();
                    contentModule.setType(type);
                    contentModule.setModuleId(moduleId);
                    contentModule.setKnowledgeId(knowledge.getId());
                    contentModule.setSortNum(maxSortNum + contents.size());
                    contents.add(contentModule);
                }
            }

            // 题目
            List<QuestionDTO> questionDTOS = (List<QuestionDTO>) module.get("questions");
            if (!CollectionUtils.isEmpty(questionDTOS)) {
                hasQuestion = true;
                List<QuestionDto> questions = saveQuestions(subjectId, questionDTOS);
                for (QuestionDto question : questions) {
                    KnowledgeContent content = new KnowledgeContent();
                    content.setType(4);
                    content.setModuleId(moduleId);
                    content.setContent(question.getId());
                    content.setSortNum(maxSortNum + contents.size());
                    contents.add(content);
                }
                questionDtos.addAll(questions);
            }else{
                // 模块里的内容
                List<String> contentStrs = (List<String>) module.get("content");
                if (!CollectionUtils.isEmpty(contentStrs)) {
                    String str = "";
                    for (String contentStr : contentStrs) {
                        if (contentStr.contains("<p")) {
                            str+=contentStr;
                        }else{
                            str+=contentStr+"<br>";
                        }
                    }
                    if(str.endsWith("<br>")){
                        str = str.substring(0,str.length()-4);
                    }
                    KnowledgeContent content = new KnowledgeContent();
                    content.setType(2);
                    content.setModuleId(moduleId);
                    content.setContent(str);
                    content.setSortNum(maxSortNum + contents.size());
                    contents.add(content);
                }
            }
        }

        super.batchInsert(contents);

        StringJoiner msgJoiner = new StringJoiner("<br>");
        StringJoiner idJoiner = new StringJoiner(",");
        for (int i = 0; i < questionDtos.size(); i++) {
            QuestionDto questionDto = questionDtos.get(i);
            idJoiner.add(questionDto.getId());
            String errorMsg = questionDto.getDataErrorMsg();
            if (!StringUtils.isEmpty(errorMsg)) {
                questionDto.setDataErrorMsg(errorMsg);
                msgJoiner.add("第" + (i + 1) + "题：" + errorMsg);
            }
        }

        QuestionImportLog importLog = new QuestionImportLog();
        if (hasQuestion) {
            // 插入导入记录
            importLog.setSubjectId(subjectId);
            importLog.setFailReason(msgJoiner.toString());
            importLog.setFileName(knowledgeContentImport.getFileName());
            importLog.setFilePath(knowledgeContentImport.getFilePath());
            importLog.setQuestionIds(idJoiner.toString());
            if (StringUtils.isEmpty(msgJoiner.toString())) {
                importLog.setStatus(2);
            } else {
                importLog.setStatus(1);
            }
            questionImportLogService.insert(importLog);
            //填充上传的文件名称数据
            updateKnowlage(knowledgeContentImport.getFileName(), importType, moduleId, importLog.getId());
        }

        return null;
    }

    public void updateKnowlage(String fileName, Integer importType, String moduleId, String importLogId) {
        //填充上传的文件名称数据
        KnowledgeManager manager = new KnowledgeManager();
        KnowledgeManager knowledgeManager = knowledgeManagerService.getById(moduleId);
        manager.setId(moduleId);
        manager.setFileNames(fileName);
        if(null != knowledgeManager){
            if(importType == 1){
                String fileNames = StringUtils.isEmpty(knowledgeManager.getFileNames()) ? "" : knowledgeManager.getFileNames()+"##";
                String importLogIds = StringUtils.isEmpty(knowledgeManager.getImportLogIds())?"":knowledgeManager.getImportLogIds() + "##";
                fileNames += fileName;
                importLogIds += importLogId;
                manager.setFileNames(fileNames);
                manager.setImportLogIds(importLogIds);
            }else {
                manager.setFileNames(fileName);
                manager.setImportLogIds(importLogId);
            }
        }
        knowledgeManagerService.update(manager);
    }

    private List<QuestionDto> saveQuestions(String subject, List<QuestionDTO> questionDTOS) {
        if (CollectionUtils.isEmpty(questionDTOS)) {
            return null;
        }
        List<QuestionDto> questions = new ArrayList<>();
        int i = 0;
        for (QuestionDTO questionDTO : questionDTOS) {
            i++;
            String errorMsg = "";
            if (!org.springframework.util.CollectionUtils.isEmpty(questionDTO.getDataErrorMsg())) {
                errorMsg = questionDTO.getDataErrorMsg().stream().collect(Collectors.joining(","));
            }
            QuestionDto questionDto = new QuestionDto();
            ObjectUtils.copyNonNullProperties(questionDTO, questionDto);
            questionDto.setOption((JSON) JSON.toJSON(questionDTO.getOptionList()));
            questionDto.setRightAnswer((JSON) JSON.toJSON(questionDTO.getRightAnswerList()));
            //根据试题类型名称获取具体试题类型
            QuestionTypeRelation typeRelation = questionTypeRelationService.queryByJyQuesTypeName(subject, questionDTO.getTypeName());
            if (typeRelation != null) {
                questionDto.setType(typeRelation.getJyQuestionType());
                questionDto.setBasicQuestionType(typeRelation.getToolQuestionType());
                questionDto.setBasicQuestionTypeName(typeRelation.getToolQuestionTypeName());
            } else {
                //其他题型
                questionDto.setType(QuestionTypeEnum.OTHER.getValue());
                questionDto.setBasicQuestionType(questionDTO.getType());
                questionDto.setBasicQuestionTypeName(questionDTO.getTypeName());
                if (StringUtils.isEmpty(errorMsg)) {
                    errorMsg = "题型未匹配";
                } else {
                    errorMsg += ";题型未匹配";
                }
            }
            questionDto.setStatus(-1);
            questionDto.setDataRight(questionDTO.getDataRight());
            questionDto.setFailReason(errorMsg);
            questionDto.setSubjectId(subject);
            questionDto.setSourceFrom(3);
            questionService.addQuestion(questionDto);
            questions.add(questionDto);
        }
        return questions;
    }

    private void fillData(List<KnowledgeContentDto> contents) {
        Iterator<KnowledgeContentDto> iterator = contents.iterator();

        while (iterator.hasNext()) {
            KnowledgeContentDto content = iterator.next();
            //类型(1、标题，2、文本   3 知识元  4 试题   5 试卷 6 学生错题 7  思维导图   8 变式题  9 练习题)
            Integer type = content.getType();

            switch (type) {
//                case 3:
//                    String kct = content.getKnowledgeId();
//                    //查询知识点
//                    Knowledge knowledge = knowledgeService.getById(kct);
//                    if (knowledge != null) {
//                        content.setTitle(knowledge.getName());
//                    }else{
//                        //知识元被删除，去掉
//                        iterator.remove();
//                        sycDel(content.getId());
//                    }
//                    break;
                case 4:
                case 8:
                case 9:
                    String qct = content.getContent();
                    //查试题
                    QuestionDto question = questionService.getQuestion(qct, null, true, true, true, false,false);
                    if(null==question){
                        //题被删除了，去掉
                        iterator.remove();
                        sycDel(content.getId());
                    }else{
                        content.setQuestion(question);
                    }
                    break;
            }

        }

    }

    private void sycDel(String id){
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            super.delete(id);
        });
    }

    /**
     * 准备条件
     *
     * @param bean
     * @param qw
     */
    private QueryWrapper prepareParams(KnowledgeContentRequest bean, QueryWrapper qw) {
        if (bean.getIds() != null && bean.getIds().length > 0) {
            qw.in("id", bean.getIds());
        }
        return qw;
    }
}
